package com.autumn.domain.repositories.plugins;

import java.util.Date;
import java.util.Properties;

import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;

import com.autumn.common.api.domain.entities.auditing.IGmtCreate;
import com.autumn.common.api.domain.entities.auditing.IGmtModified;

/**
 * 审计执行列新插件
 * 
 * @author 老码农
 *
 *         2017-12-08 13:07:10
 */
@Intercepts({ @Signature(type = Executor.class, method = "update", args = { MappedStatement.class, Object.class }) })
public class AuditingExecutorUpdatePlugin extends AbstractAuditingPlugin {

	@Override
	public Object intercept(Invocation invocation) throws Throwable {
		MappedStatement ms = (MappedStatement) invocation.getArgs()[0];
		MapperAuditingInfo mapperInfo = getMapperAuditingInfo(ms.getId());
		if (mapperInfo != null && !mapperInfo.getAuditingMethod().equals(AuditingMethodEnum.UN_KNOWN)) {
			AuditingMethodEnum aMethodEnum = mapperInfo.getAuditingMethod();
			switch (aMethodEnum) {
			case INSERT:
				if (mapperInfo.isGmtCreate()) {
					insertGmt(invocation.getArgs()[1], mapperInfo);
				}
				break;
			case UPDATE:
				if (mapperInfo.isGmtModified()) {
					updateGmt(invocation.getArgs()[1], mapperInfo);
				}
			case DELETE_BY_PRIMARY_KEY:
				if (mapperInfo.isSoftDelete()) {

				}
				break;
			default:
				break;
			}
		}
		return invocation.proceed();
	}

	private void insertGmt(Object entity, MapperAuditingInfo mapperInfo) {
		IGmtCreate gc = (IGmtCreate) entity;
		gc.setGmtCreate(new Date());
		if (mapperInfo.isGmtModified()) {
			IGmtModified gm = (IGmtModified) entity;
			gm.setGmtModified(null);
		}
	}

	private void updateGmt(Object entity, MapperAuditingInfo mapperInfo) {
		IGmtModified gm = (IGmtModified) entity;
		gm.setGmtModified(new Date());
	}

	@Override
	public Object plugin(Object target) {
		return Plugin.wrap(target, this);
	}

	@Override
	public void setProperties(Properties properties) {

	}
}
